<template>
  <div class="app-container">
    <el-row :gutter="20">
      <el-col :span="5">
        <el-card shadow="never" class="table-container">
          <el-radio-group v-model="isCollapse" @change="changeWorkType">
            <el-radio-button :value="1"
              ><el-icon :style="iconStyle"><User /></el-icon
              >按人看</el-radio-button
            >
            <el-radio-button :value="2"
              ><el-icon :style="iconStyle"><Operation /></el-icon
              >汇总看</el-radio-button
            >
            <el-radio-button :value="3"
              ><el-icon :style="iconStyle"><DataLine /></el-icon
              >统&nbsp;计</el-radio-button
            >
          </el-radio-group>
          <div style="min-height: 250px; margin-top: 15px" v-if="leftNav == 2">
            <el-tree
              :data="workPaperType"
              :props="defaultProps"
              @node-click="handleNodeClick"
              :default-expand-all="true"
              :current-node-key="1"
              node-key="value"
              :highlight-current="true"
            />
          </div>
          <div style="min-height: 250px; margin-top: 15px" v-if="leftNav == 1">
            <el-text class="mx-1">我收到的</el-text>
            <ul class="left-nav-user" mt-2>
              <li
                v-for="(item, index) in receiptUser"
                :key="index"
                mb-2
                :class="{ active: index == current }"
                @click="handleReceiptActive(index, item.id)"
              >
                <div style="position: relative">
                  <el-avatar
                    :src="item.avatar"
                    :size="32"
                    class="role-avatar"
                  />
                  <span style="position: absolute; top: 0; left: 40px">{{
                    item.nickname
                  }}</span>
                </div>
              </li>
            </ul>
          </div>
        </el-card>
      </el-col>
      <el-col :span="19">
        <el-card shadow="never" class="table-container">
          <template #header>
            <div class="flex justify-between">
              <div>
                <el-button
                  v-hasPerm="['workpaper@del']"
                  type="danger"
                  v-if="removeIds.length > 0"
                  @click="handleDelete()"
                  ><i-ep-delete />删除</el-button
                >
              </div>
              <div style="width: 100%">
                <div
                  v-if="isShowSearchBtn && leftNav == 2"
                  style="display: inline-block; float: left"
                >
                  <el-form
                    class="queryParams"
                    ref="queryFormRef"
                    :model="queryParams"
                    :inline="true"
                  >
                    <el-form-item label="按时间">
                      <el-date-picker
                        class="!w-[240px]"
                        v-model="dateTimeRange"
                        type="daterange"
                        range-separator="~"
                        start-placeholder="开始时间"
                        end-placeholder="截止时间"
                        value-format="YYYY-MM-DD"
                      />
                    </el-form-item>
                    <el-form-item label="按人员">
                      <el-select
                        v-model="checkUserIds"
                        multiple
                        placeholder="请选择人员"
                        style="width: 240px"
                        @click="openDialog"
                      >
                        <el-option
                          v-for="item in userOptions"
                          :key="item.value"
                          :label="item.label"
                          :value="item.value"
                        />
                      </el-select>
                    </el-form-item>
                    <el-form-item label="状态" prop="is_read">
                      <el-select
                        v-model="queryParams.is_read"
                        placeholder="全部"
                        clearable
                        class="!w-[100px]"
                        @change="handleQuery"
                      >
                        <el-option label="未读" :value="2" />
                        <el-option label="已读" :value="1" />
                      </el-select>
                    </el-form-item>
                    <el-form-item>
                      <el-button type="primary" @click="handleQuery">
                        <i-ep-search />搜索
                      </el-button>
                      <el-button @click="resetQuery">
                        <i-ep-refresh />重置
                      </el-button>
                    </el-form-item>
                  </el-form>
                </div>
                <div style="display: inline-block; float: right">
                  <el-button
                    v-if="leftNav == 1"
                    class="ml-3"
                    @click="handleSearchShowBtn"
                    icon="Search"
                    circle
                  />
                  <el-button
                    class="ml-3"
                    title="刷新"
                    @click="handleQuery"
                    icon="Refresh"
                    circle
                  />
                </div>
              </div>
            </div>
          </template>
          <el-tabs
            v-model="activeName"
            class="demo-tabs"
            @tab-click="handleClick"
            v-if="leftNav == 1"
          >
            <el-tab-pane label="工作日报" name="day" />
            <el-tab-pane label="工作周报" name="week" />
            <el-tab-pane label="工作月报" name="month" />
          </el-tabs>
          <el-table
            v-if="leftNav != 3"
            ref="dataTableRef"
            v-loading="loading"
            :data="MessageList"
            @selection-change="handleSelectionChange"
            @sort-change="handleSortChange"
          >
            <el-table-column type="selection" width="55" align="center" />
            <el-table-column
              key="id"
              label="ID"
              align="center"
              prop="id"
              width="100"
              sortable="custom"
            />
            <el-table-column label="汇报人">
              <template #default="scope">
                {{ scope.row.nickname }}
              </template>
            </el-table-column>
            <el-table-column label="汇报内容" prop="current_content" />
            <el-table-column label="计划内容" prop="next_content" />
            <el-table-column label="其他" prop="remark" />
            <el-table-column label="汇报时间" prop="created_at" width="200" />
            <el-table-column fixed="right" label="操作" width="220">
              <template #default="scope">
                <el-button
                  type="success"
                  circle
                  @click="openReviewDrawer(scope.row.id)"
                  title="查看"
                >
                  <i-ep-promotion />
                </el-button>
              </template>
            </el-table-column>
          </el-table>
          <pagination
            v-if="total > 0 && leftNav != 3"
            v-model:total="total"
            v-model:page="queryParams.p"
            v-model:limit="queryParams.limit"
            @pagination="handleQuery"
          />
          <div v-show="leftNav == 3" id="chart" style="height: 400px"></div>
        </el-card>
      </el-col>
    </el-row>
    <!-- 角色表单弹窗 -->
    <el-dialog
      v-model="dialog.visible"
      title="用户选择"
      width="65%"
      @close="closeDialog"
    >
      <el-row :gutter="20" style="padding: 25px">
        <el-col :span="6">
          <el-card shadow="never" class="table-container">
            <el-tree
              :data="orgTreeData"
              :props="defaultProps"
              :default-expand-all="true"
              @node-click="handleOrg"
            />
          </el-card>
        </el-col>
        <el-col :span="10">
          <el-card shadow="never" class="table-container">
            <template #header>
              <div class="flex justify-between">
                <div style="display: inline-block">
                  <el-form
                    ref="queryUserFormRef"
                    :model="queryUserParams"
                    :inline="true"
                    style="margin-bottom: -16px"
                  >
                    <el-form-item prop="title" style="margin-right: 5px">
                      <el-input
                        v-model="queryUserParams.title"
                        placeholder="请输入用户名"
                        clearable
                        style="width: 150px"
                        @keyup.enter="handleUserQuery"
                      />
                    </el-form-item>
                    <el-form-item style="margin-right: 0">
                      <el-button type="primary" @click="handleUserQuery"
                        ><i-ep-search />搜索</el-button
                      >
                      <el-button @click="resetUserQuery">
                        <i-ep-refresh />
                        重置</el-button
                      >
                    </el-form-item>
                  </el-form>
                </div>
              </div>
            </template>
            <el-table :data="userList">
              <el-table-column width="45px">
                <template #default="scope">
                  <el-button
                    icon="Plus"
                    circle
                    @click="addUser(scope.row, 'add')"
                  />
                </template>
              </el-table-column>
              <el-table-column property="avatar" label="头像" width="65px">
                <template #default="scope">
                  <el-avatar
                    :src="scope.row.avatar"
                    :size="32"
                    class="role-avatar"
                  />
                </template>
              </el-table-column>
              <el-table-column property="nickname" label="用户名" />
              <el-table-column property="username" label="账号" />
            </el-table>
            <pagination
              v-if="totalUser > 0"
              v-model:total="totalUser"
              v-model:page="queryUserParams.p"
              v-model:limit="queryUserParams.limit"
              @pagination="handleUserQuery"
            />
          </el-card>
        </el-col>
        <el-col :span="8">
          <el-card shadow="never" class="table-container">
            <template #header>
              <div class="flex justify-between">
                <span class="role-avatar">已选择：{{ checkUserNumber }}</span>
                <el-button
                  type="danger"
                  @click="addUser([], 'remove', true)"
                  circle
                  aria-label="移除"
                  ><i-ep-minus
                /></el-button>
              </div>
            </template>
            <el-table :data="checkUserLst">
              <el-table-column width="45px">
                <template #default="scope">
                  <el-button
                    type="danger"
                    icon="Minus"
                    circle
                    @click="addUser(scope.row, 'remove')"
                  />
                </template>
              </el-table-column>
              <el-table-column property="avatar" label="头像" width="65px">
                <template #default="scope">
                  <el-avatar
                    :src="scope.row.avatar"
                    :size="32"
                    class="role-avatar"
                  />
                </template>
              </el-table-column>
              <el-table-column property="nickname" label="用户名" />
            </el-table>
          </el-card>
        </el-col>
      </el-row>
      <template #footer>
        <div style="flex: auto">
          <el-button @click="closeDialog">取消</el-button>
          <el-button type="primary" @click="confirmAuthUser">确认</el-button>
        </div>
      </template>
    </el-dialog>
    <el-drawer v-model="viewDrawer" title="工作汇报" direction="rtl" size="65%">
      <el-descriptions class="margin-top" :column="3" border>
        <el-descriptions-item>
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <CollectionTag />
              </el-icon>
              汇报人
            </div>
          </template>
          {{ formDataInfo.nickname }}
        </el-descriptions-item>
        <el-descriptions-item>
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <OfficeBuilding />
              </el-icon>
              所属部门
            </div>
          </template>
          {{ formDataInfo.org_name }}
        </el-descriptions-item>
        <el-descriptions-item>
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <Menu />
              </el-icon>
              类型
            </div>
          </template>
          {{ formDataInfo.type_name }}
        </el-descriptions-item>
        <el-descriptions-item :span="3">
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <Clock />
              </el-icon>
              汇报时间
            </div>
          </template>
          {{ formDataInfo.created_at }}
        </el-descriptions-item>
        <el-descriptions-item :span="3" v-if="formDataInfo.is_owner == 1">
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <Flag />
              </el-icon>
              接收人
            </div>
          </template>
          <el-tag v-for="item in formDataInfo.users" :key="item" mr-1>{{
            item
          }}</el-tag>
        </el-descriptions-item>

        <el-descriptions-item :span="3">
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <Tickets />
              </el-icon>
              工作内容
            </div>
          </template>
          {{ formDataInfo.current_content }}
        </el-descriptions-item>
        <el-descriptions-item :span="3">
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <Compass />
              </el-icon>
              计划内容
            </div>
          </template>
          {{ formDataInfo.next_content }}
        </el-descriptions-item>
        <el-descriptions-item :span="3">
          <template #label>
            <div class="cell-item">
              <el-icon :style="iconStyle">
                <CollectionTag />
              </el-icon>
              其他事项
            </div>
          </template>
          {{ formDataInfo.remark }}
        </el-descriptions-item>
      </el-descriptions>
      <el-form
        ref="userFormRef"
        label-position="right"
        label-width="auto"
        mt-4
        :model="receiptForm"
        v-if="receiptForm.is_read == 0"
      >
        <el-form-item label="评论反馈">
          <el-input v-model="receiptForm.reply_content" type="textarea" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div style="flex: auto">
          <el-button @click="viewDrawer = false">关闭</el-button>
          <el-button
            type="primary"
            v-if="receiptForm.is_read == 0"
            @click="handleSubmit"
            >确认</el-button
          >
        </div>
      </template>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
defineOptions({
  name: "WorkPaperBoard",
  inheritAttrs: false,
});

import * as echarts from "echarts";
import {
  deleteWorkPaper,
  getBoardPage,
  getWorkPaperForm,
  receiptWorkPaper,
  getReceiptUser,
} from "@/api/workPaper";
import {
  WorkPaperForm,
  WorkPaperPage,
  WorkPaperQuery,
  WorkPaperInfo,
  ReceiptUser,
  ReceiptForm,
} from "@/api/workPaper/types";
import { getUserPage } from "@/api/role";
import { orgTree } from "@/api/organization";
import { UserQuery, UserPageVO } from "@/api/user/types";
const activeName = ref("day");
const queryFormRef = ref(ElForm);
const queryUserFormRef = ref(ElForm);
const userFormRef = ref(ElForm); // 表单
const loading = ref(false);
const total = ref(0);
const totalUser = ref(0);
const isShowSearchBtn = ref(false);
const viewDrawer = ref(false);
const isCollapse = ref(1);
const leftNav = ref(1);
const removeIds = ref([]); // 删除ID集合 用于批量删除
const selectedRows = ref([]);
const workPaperType = ref([
  {
    title: "我收到的",
    value: 0,
    children: [
      {
        title: "工作日报",
        value: 1,
      },
      {
        title: "工作周报",
        value: 2,
      },
      {
        title: "工作月报",
        value: 3,
      },
    ],
  },
]);
const queryParams = reactive<WorkPaperQuery>({
  p: 1,
  limit: 10,
  type: 1,
  query_type: 1,
  time: [] as any,
});
const queryUserParams = reactive<UserQuery>({
  p: 1,
  limit: 10,
});
const iconStyle = computed(() => {
  const marginMap = {
    large: "8px",
    default: "6px",
    small: "4px",
  };
  return {
    marginRight: marginMap.default,
  };
});
const MessageList = ref<WorkPaperPage[]>();
const receiptUser = ref<ReceiptUser[]>();
const userOptions = ref<OptionType[]>();
const userList = ref<UserPageVO[]>();
const checkUserLst = ref<UserPageVO[]>();
const checkUserIds = ref([]);
const checkUserNumber = ref(0);
const dateTimeRange = ref([]);
watch(dateTimeRange, (newVal) => {
  Object.assign(queryParams, { time: newVal });
});
const dialog = reactive({
  title: "",
  visible: false,
});
const formData = reactive<WorkPaperForm>({
  id: undefined,
  sort: 0,
});
const receiptForm = reactive<ReceiptForm>({});
const formDataInfo = reactive<WorkPaperInfo>(<WorkPaperInfo>{});
const orgTreeData = ref<OptionType[]>(); //组织架构下拉数据源
const defaultProps = ref({
  children: "children",
  label: "title",
});
const current = ref(0);

const handleNodeClick = (data: any) => {
  queryParams.type = data.value;
  handleQuery();
};

const chart = ref<any>("");

const options = {
  tooltip: {
    position: "top",
    formatter: function (p) {
      const format = echarts.time.format(p.data[0], "{yyyy}-{MM}-{dd}", false);
      return format + ": " + p.data[1];
    },
  },
  visualMap: {
    min: 0,
    max: 1000,
    calculable: true,
    orient: "vertical",
    left: "670",
    top: "center",
  },
  calendar: [
    {
      orient: "vertical",
      range: "2015",
    },
    {
      left: 300,
      orient: "vertical",
      range: "2016",
    },
    {
      left: 520,
      cellSize: [20, "auto"],
      bottom: 10,
      orient: "vertical",
      range: "2017",
      dayLabel: {
        margin: 5,
      },
    },
  ],
  series: [
    {
      type: "heatmap",
      coordinateSystem: "calendar",
      calendarIndex: 0,
      data: getVirtualData(2015),
    },
    {
      type: "heatmap",
      coordinateSystem: "calendar",
      calendarIndex: 1,
      data: getVirtualData(2016),
    },
    {
      type: "heatmap",
      coordinateSystem: "calendar",
      calendarIndex: 2,
      data: getVirtualData(2017),
    },
  ],
};

function changeWorkType(values: any) {
  leftNav.value = values;
  if (leftNav.value == 1) {
    queryParams.type = undefined;
    queryParams.query_type = 1;
    userList.value = [];
    checkUserLst.value = [];
    checkUserIds.value = [];
    checkUserNumber.value = 0;
    handleReceiptUserQuery();
  } else if (leftNav.value == 2) {
    queryParams.type = 1;
    queryParams.query_type = 2;
  } else {
    chart.value.setOption(options);
    // 大小自适应
    window.addEventListener("resize", () => {
      chart.value.resize();
    });
  }
  handleQuery();
}

function handleReceiptUserQuery() {
  getReceiptUser()
    .then(({ data }) => {
      receiptUser.value = data;
      queryParams.receipt_user_id = data[0].id;
    })
    .finally(() => {});
}

const handleClick = (tab: any, event: Event) => {
  if (tab.props.name == "day") {
    queryParams.type = 1;
  } else if (tab.props.name == "week") {
    queryParams.type = 2;
  } else {
    queryParams.type = 3;
  }
  handleQuery();
};

/** 组织架构树 */
function orgQuery() {
  orgTree()
    .then(({ data }) => {
      orgTreeData.value = data;
      const options: OptionType = orgTreeData.value[0];
      queryUserParams.id =
        typeof options.value === "string"
          ? parseInt(options.value)
          : options.value;
      getUserPage(queryUserParams)
        .then(({ data }) => {
          userList.value = data.items;
          totalUser.value = data.total;
        })
        .finally(() => {});
    })
    .finally(() => {});
}

function addUser(user?: UserPageVO, type?: string, isAll?: boolean) {
  if (user != undefined) {
    if (type === "add") {
      if (checkUserLst.value == undefined) {
        checkUserLst.value = [];
      }
      if (userOptions.value == undefined) {
        userOptions.value = [];
      }
      checkUserLst.value.push(user);
      if (user.id != undefined) {
        checkUserIds.value.push(user.id);
        userOptions.value.push({
          label: user.nickname,
          value: user.id,
        });
      }
      if (userList.value != undefined) {
        userList.value = userList.value.filter((item) => {
          return item.id !== user.id;
        });
      }
    } else {
      if (isAll === true) {
        checkUserIds.value = [];
        if (userList.value != undefined && checkUserLst.value != undefined) {
          const mergedArray: UserPageVO[] = [
            ...userList.value,
            ...checkUserLst.value,
          ];
          userList.value = [
            ...new Map(mergedArray.map((item) => [item.id, item])).values(),
          ];
          checkUserLst.value = [];
        }
        userOptions.value = [];
      } else {
        userOptions.value = userOptions.value.filter((item) => {
          return item.value !== user.id;
        });
        if (checkUserLst.value != undefined) {
          checkUserLst.value = checkUserLst.value.filter((item) => {
            return item.id !== user.id;
          });
        }
        if (checkUserIds.value != undefined) {
          checkUserIds.value = checkUserIds.value.filter((item) => {
            return item !== user.id;
          });
        }
        if (userList.value != undefined) {
          //先移除后添加
          userList.value = userList.value.filter((item) => {
            return item.id !== user.id;
          });
        }
        if (userList.value != undefined) {
          userList.value?.push(user);
        }
      }
    }
    checkUserNumber.value =
      checkUserLst.value != undefined ? checkUserLst.value.length : 0;
  }
}

/**
 * 确认选择
 */
function confirmAuthUser() {
  if (checkUserIds.value) {
    formData.user_id = checkUserIds.value;
  }
  closeDialog();
}

/**
 * 查询组织架构树下的用户
 * @param tree
 */
function handleOrg(tree: any) {
  queryUserParams.id = tree.id;
  getUserPage(queryUserParams)
    .then(({ data }) => {
      userList.value = data.items;
    })
    .finally(() => {});
}
function handleUserQuery() {
  getUserPage(queryUserParams)
    .then(({ data }) => {
      userList.value = data.items;
    })
    .finally(() => {});
}
/** 查询 */
function handleQuery() {
  loading.value = true;
  if (checkUserIds.value) {
    queryParams.review_id = checkUserIds.value.join(",");
  }
  getBoardPage(queryParams)
    .then(({ data }) => {
      MessageList.value = data.items;
      total.value = data.total;
    })
    .finally(() => {
      loading.value = false;
    });
}
/** 重置查询 */
function resetQuery() {
  queryFormRef.value.resetFields();
  queryParams.p = 1;
  handleQuery();
}

function resetUserQuery() {
  queryUserFormRef.value.resetFields();
  queryUserParams.p = 1;
  handleUserQuery();
}

function openReviewDrawer(id: any) {
  viewDrawer.value = true;
  getWorkPaperForm(id)
    .then(({ data }) => {
      Object.assign(formDataInfo, { ...data });
      receiptForm.id = data.id;
      receiptForm.is_read = data.is_read;
    })
    .finally(() => {});
}

/** 打开表单弹窗 */
function openDialog() {
  dialog.visible = true;
  orgQuery();
}

/** 保存提交 */
function handleSubmit() {
  userFormRef.value.validate((valid: any) => {
    if (valid) {
      receiptWorkPaper(receiptForm)
        .then(() => {
          resetForm();
          viewDrawer.value = false;
          ElMessage.success("反馈成功");
        })
        .finally(() => ({}));
    }
  });
}

/** 关闭表单弹窗 */
function closeDialog() {
  dialog.visible = false;
}

function handleReceiptActive(index: number, id: any) {
  if (index == current.value) {
    current.value = null; // 再次点击相同元素，删除activeClass
  } else {
    current.value = index;
  }
  queryParams.receipt_user_id = id;
  handleQuery();
}

/** 重置表单 */
function resetForm() {
  userFormRef.value.resetFields();
  userFormRef.value.clearValidate();
  selectedRows.value = [];
  formData.id = undefined;
  formData.user_id = [];
  handleQuery();
}

/** 删除 */
function handleDelete(id?: number) {
  const ids = id || removeIds.value;
  if (!ids) {
    ElMessage.warning("请勾选删除项");
    return;
  }
  ElMessageBox.confirm("确认删除已选中的数据项?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(() => {
    loading.value = true;
    deleteWorkPaper({ ids: ids })
      .then(() => {
        ElMessage.success("删除成功");
        handleQuery();
      })
      .finally(() => (loading.value = false));
  });
}

/** 行选中 */
function handleSelectionChange(selection: any) {
  removeIds.value = selection.map((item: any) => item.id);
}

//收起展开搜索按钮
function handleSearchShowBtn() {
  isShowSearchBtn.value = isShowSearchBtn.value === false;
}

/** 排序 */
function handleSortChange(data: any) {
  const { prop, order } = data;
  if (prop === "id") {
    if (order === "ascending") {
      queryParams.sort = "+id";
    } else {
      queryParams.sort = "-id";
    }
    handleQuery();
  }
}

function getVirtualData(year: number) {
  const date = +echarts.time.parse(year + "-01-01");
  const end = +echarts.time.parse(+year + 1 + "-01-01");
  const dayTime = 3600 * 24 * 1000;
  const data = [];
  for (let time = date; time < end; time += dayTime) {
    data.push([
      echarts.time.format(time, "{yyyy}-{MM}-{dd}", false),
      Math.floor(Math.random() * 1000),
    ]);
  }
  return data;
}
onMounted(() => {
  handleReceiptUserQuery();
  handleQuery();
  chart.value = markRaw(
    echarts.init(document.getElementById("chart") as HTMLDivElement)
  );
});
</script>

<style lang="scss" scoped>
::v-deep(.el-tree-node__content) {
  height: 38px !important;
  line-height: 38px !important;
  border-radius: 8px !important;
}
.left-nav-user {
  list-style: none;
  width: 100%;
}
.left-nav-user li {
  height: 48px !important;
  line-height: 34px !important;
  border-radius: 8px !important;
  cursor: pointer;
  padding: 8px;
  font-size: var(--el-font-size-base);
  color: var(--el-tree-text-color);
}
.left-nav-user li.active {
  background-color: #f5f7fa;
  border: 1px solid #409eff;
  color: #409eff;
}
.queryParams .el-form-item {
  margin-bottom: 0;
}
.message-avatar {
  display: inline-block;
  position: relative;
}
.message-avatar .remove-user {
  position: absolute;
  right: 0;
  top: -10px;
  color: var(--el-color-danger);
  cursor: pointer;
}
.role-avatar {
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
